﻿using System;
using System.Web;
using System.Data.SqlClient;
using System.Configuration;

namespace Wild2.Models.Auth
{
    public class AuthOnSite
    {
        public static string GetSessionHash()
        {
            return HttpContext.Current.Session[Wild2.Models.Constants.SessionConstants.GUID].ToString();
        }

        public static bool IsSiteAdmin(Int32 userId)
        {
            if (userId == 1) return true;
            return false;
        }

        public static bool ChangePassword(Int32 userId, string passwordOld, string passwordNew)
        {
            if (passwordNew.Length < 6) return false;
            if (passwordNew.Length > 50) return false;
            using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnect"].ConnectionString))
            {
                using (SqlCommand cmd = new SqlCommand("SELECT TOP(1) COUNT(ID) FROM [Users] WHERE ([ID] = @ID) AND ([Password] = @Pass)", conn))
                {
                    cmd.Parameters.Add("@ID", System.Data.SqlDbType.Int).Value = userId;
                    cmd.Parameters.Add("@Pass", System.Data.SqlDbType.NVarChar, 50).Value = MD5Helper.GetMd5Hash(passwordOld);
                    cmd.Connection.Open();
                    if (Convert.ToInt32(cmd.ExecuteScalar()) == 0) return false;
                    cmd.Connection.Close();
                }
                using (SqlCommand cmd = new SqlCommand("UPDATE Users SET [Password] = @NewPass WHERE ([ID] = @ID) AND ([Password] = @Pass)", conn))
                {
                    cmd.Parameters.Add("@ID", System.Data.SqlDbType.Int).Value = userId;
                    cmd.Parameters.Add("@Pass", System.Data.SqlDbType.NVarChar, 50).Value = MD5Helper.GetMd5Hash(passwordOld);
                    cmd.Parameters.Add("@NewPass", System.Data.SqlDbType.NVarChar, 50).Value = MD5Helper.GetMd5Hash(passwordNew);
                    cmd.Connection.Open();
                    cmd.ExecuteNonQuery();
                    cmd.Connection.Close();
                }
            }
            return true;
        }

        /// <summary>
        /// Функция которая возвращает идентификационный номер зарегистрированного пользователя из сессии.
        /// </summary>
        /// <returns>Идентификационный номер пользователя под которым он зарегистрирован в базе</returns>
        public static Int32? GetUserId()
        {
            Int32? userId = null;
            Object o = HttpContext.Current.Session[Wild2.Models.Constants.SessionConstants.USERID];
            if (o != null) userId = Convert.ToInt32(o);
            return userId;
        }

        public static String GetUserNick()
        {
            String userNick = null;
            Object o = HttpContext.Current.Session[Wild2.Models.Constants.SessionConstants.USERNICK];
            if (o != null)
            {
                userNick = o.ToString();
            }
            else
            {
                Int32? userId = null;
                Object u = HttpContext.Current.Session[Wild2.Models.Constants.SessionConstants.USERID];
                if (u != null) userId = Convert.ToInt32(u);
                if (userId.HasValue)
                {
                    using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnect"].ConnectionString))
                    {
                        using (SqlCommand cmd = new SqlCommand("SELECT TOP(1) [Nick] FROM [Users] WHERE [ID] = @ID", conn))
                        {
                            cmd.Parameters.Add("@ID", System.Data.SqlDbType.Int).Value = userId.Value;
                            cmd.Connection.Open();
                            using (SqlDataReader reader = cmd.ExecuteReader())
                            {
                                while (reader.Read())
                                {
                                    userNick = reader["Nick"].ToString();
                                    HttpContext.Current.Session[Wild2.Models.Constants.SessionConstants.USERNICK] = userNick;
                                }
                            }
                            cmd.Connection.Close();
                        }
                    }
                }
            }
            return userNick;
        }

        public static String GetUserNick(Int32 userId)
        {
            String userNick = "";
            using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnect"].ConnectionString))
            {
                using (SqlCommand cmd = new SqlCommand("SELECT TOP(1) [Nick] FROM [Users] WHERE [ID] = @ID", conn))
                {
                    cmd.Parameters.Add("@ID", System.Data.SqlDbType.Int).Value = userId;
                    cmd.Connection.Open();
                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            userNick = reader["Nick"].ToString();
                        }
                    }
                    cmd.Connection.Close();
                }
            }
            return userNick;
        }

        /// <summary>
        /// Получение приватного ключа зарегистрированного пользователя.
        /// </summary>
        /// <returns>Возвращает приватный ключ зарегистрированного пользователя</returns>
        public static string GetUserPrivateKey()
        {
            String privateKey = "";
            Int32? userId = null;
            Object o = HttpContext.Current.Session[Wild2.Models.Constants.SessionConstants.USERID];
            if (o != null) userId = Convert.ToInt32(o);
            if (userId.HasValue)
            {
                using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnect"].ConnectionString))
                {
                    using (SqlCommand cmd = new SqlCommand("SELECT TOP(1) [PrivateKey] FROM [Users] WHERE [ID] = @ID", conn))
                    {
                        cmd.Parameters.Add("@ID", System.Data.SqlDbType.Int).Value = userId.Value;
                        cmd.Connection.Open();
                        using (SqlDataReader reader = cmd.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                privateKey = reader["PrivateKey"].ToString();
                            }
                        }
                        cmd.Connection.Close();
                    }
                }
            }
            return privateKey;
        }

        /// <summary>
        /// Генерация приватного ключа для зарегистрированного пользователя и изменение его в базе.
        /// </summary>
        /// <returns>Возвращает приватный ключ зарегистрированного пользователя</returns>
        public static string GetUserPrivateKey(bool generateNewKey)
        {
            String privateKey = Guid.NewGuid().ToString();
            Int32? userId = null;
            Object o = HttpContext.Current.Session[Wild2.Models.Constants.SessionConstants.USERID];
            if (o != null) userId = Convert.ToInt32(o);
            if (userId.HasValue)
            {
                using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnect"].ConnectionString))
                {
                    using (SqlCommand cmd = new SqlCommand("UPDATE [Users] SET [PrivateKey] = @PKEY WHERE [ID] = @ID", conn))
                    {
                        cmd.Parameters.Add("@ID", System.Data.SqlDbType.Int).Value = userId.Value;
                        cmd.Parameters.Add("@PKEY", System.Data.SqlDbType.NVarChar, 40).Value = privateKey;
                        cmd.Connection.Open();
                        cmd.ExecuteNonQuery();
                        cmd.Connection.Close();
                    }
                }
            }
            return privateKey;
        }

        /// <summary>
        /// Получение публичного ключа зарегистрированного пользователя.
        /// </summary>
        /// <returns>Возвращает публичный ключ зарегистрированного пользователя</returns>
        public static string GetUserPublicKey()
        {
            String publicKey = "";
            Int32? userId = null;
            Object o = HttpContext.Current.Session[Wild2.Models.Constants.SessionConstants.USERID];
            if (o != null) userId = Convert.ToInt32(o);
            if (userId.HasValue)
            {
                using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnect"].ConnectionString))
                {
                    using (SqlCommand cmd = new SqlCommand("SELECT TOP(1) [PubKey] FROM [Users] WHERE [ID] = @ID", conn))
                    {
                        cmd.Parameters.Add("@ID", System.Data.SqlDbType.Int).Value = userId.Value;
                        cmd.Connection.Open();
                        using (SqlDataReader reader = cmd.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                publicKey = reader["PubKey"].ToString();
                            }
                        }
                        cmd.Connection.Close();
                    }
                }
            }
            return publicKey;
        }

        /// <summary>
        /// Генерация публичного ключа для зарегистрированного пользователя и изменение его в базе.
        /// </summary>
        /// <returns>Возвращает публичный ключ зарегистрированного пользователя</returns>
        public static string GetUserPublicKey(bool generateNewKey)
        {
            String publicKey = Guid.NewGuid().ToString();
            Int32? userId = null;
            Object o = HttpContext.Current.Session[Wild2.Models.Constants.SessionConstants.USERID];
            if (o != null) userId = Convert.ToInt32(o);
            if (userId.HasValue)
            {
                using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnect"].ConnectionString))
                {
                    using (SqlCommand cmd = new SqlCommand("UPDATE [Users] SET [PubKey] = @PKEY WHERE [ID] = @ID", conn))
                    {
                        cmd.Parameters.Add("@ID", System.Data.SqlDbType.Int).Value = userId.Value;
                        cmd.Parameters.Add("@PKEY", System.Data.SqlDbType.NVarChar, 40).Value = publicKey;
                        cmd.Connection.Open();
                        cmd.ExecuteNonQuery();
                        cmd.Connection.Close();
                    }
                }
            }
            return publicKey;
        }

        /// <summary>
        /// Авторизация пользователя по приватному ключу.
        /// GUID может быть получен например из Cookies и вызываться при каждом обращении к сайту в Global.asax
        /// </summary>
        /// <param name="privateKey">Приватный ключ пользователя</param>
        /// <returns>Идентификационный номер пользователя по которому он зарегистрирован в базе</returns>
        public static Int32? AuthGUID(String privateKey)
        {
            Int32? userId = null;
            String version = "pda";
            using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnect"].ConnectionString))
            {
                using (SqlCommand cmd = new SqlCommand("SELECT TOP(1) [ID], [Skin] FROM [Users] WHERE [PrivateKey] = @PKEY", conn))
                {
                    cmd.Parameters.Add("@PKEY", System.Data.SqlDbType.NVarChar, 40).Value = privateKey;
                    cmd.Connection.Open();
                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            userId = Convert.ToInt32(reader["ID"]);
                            if (reader["Skin"] != DBNull.Value)
                            {
                                if (!string.IsNullOrEmpty(reader["Skin"].ToString()))
                                {
                                    version = reader["Skin"].ToString();
                                }
                            }
                        }
                    }
                    cmd.Connection.Close();
                }
            }
            if (userId.HasValue)
            {
                HttpContext.Current.Session[Wild2.Models.Constants.SessionConstants.USERID] = userId.Value;
                HttpContext.Current.Session[Wild2.Models.Constants.SessionConstants.VERSION] = version;
                UserIP.UserIPLog(userId.Value);
            }
            return userId;
        }

        /// <summary>
        /// Авторизация пользователя по паролю.
        /// </summary>
        /// <param name="userName">Логин(Ник) пользователя</param>
        /// <param name="password">Пароль пользователя</param>
        /// <returns></returns>
        public static Int32? AuthPassword(String userName, String password)
        {
            Int32? userId = null;
            String version = "pda";
            String privateKey = "";
            using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnect"].ConnectionString))
            {
                using (SqlCommand cmd = new SqlCommand("SELECT TOP(1) [ID], [PrivateKey], [Skin] FROM [Users] WHERE ([Nick] = @UNAME) AND ([Password] = @PASS)", conn))
                {
                    cmd.Parameters.Add("@UNAME", System.Data.SqlDbType.NVarChar, 20).Value = userName;
                    cmd.Parameters.Add("@PASS", System.Data.SqlDbType.NVarChar, 50).Value = MD5Helper.GetMd5Hash(password);
                    cmd.Connection.Open();
                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            userId = Convert.ToInt32(reader["ID"]);
                            privateKey = reader["PrivateKey"].ToString();
                            if (reader["Skin"] != DBNull.Value)
                            {
                                if (!string.IsNullOrEmpty(reader["Skin"].ToString()))
                                {
                                    version = reader["Skin"].ToString();
                                }
                            }
                        }
                    }
                    cmd.Connection.Close();
                }
            }
            if (userId.HasValue)
            {
                HttpContext.Current.Session[Wild2.Models.Constants.SessionConstants.USERID] = userId.Value;
                HttpContext.Current.Session[Wild2.Models.Constants.SessionConstants.VERSION] = version;
                UserIP.UserIPLog(userId.Value);
                HttpCookie cookie = new HttpCookie("PrivateKey");
                cookie.Value = privateKey;
                cookie.Expires = DateTime.Now.AddMonths(6);
                HttpContext.Current.Response.Cookies.Add(cookie);
            }
            return userId;
        }
    }
}